#ifndef BANK_H_
#define BANK_H_

#include <iostream>
#include <queue>
#include <iostream>
#include <vector>
using namespace std;


class Customer
{
private:
    int arriveTime;
    int getServeTime;
    int WaitingTime;
public:
    Customer(int arrTime):arriveTime(arrTime){};
    Customer &  set_getServeTime(int gseTime)
    {
        getServeTime=gseTime;
        return *this;
    };
    Customer & set_WaitingTime()
    {
        WaitingTime=getServeTime-arriveTime;
        return *this;
    };
    int get_WaitingTime()const{return WaitingTime;};
};


class Bank
{
public:
private:
    int currTime;//计时器，当前的时间，单位s
    //银行基础属性
    int workTime;//银行每日上班时长，单位秒。
    int windowNums;//银行窗口数。
    // 银行考核KPI
    double sumCusServed=-1;//总服务顾客数(营业时间结束时，仍然可能有未服务的顾客)
    double lastCus=-1;//营业结束时，仍在队列中，没有服务的客户。
    double sumCusArrive=-1;//总到达顾客数。
    double sumWaitingTime=-1;//所有已服务客户的等待时间
    double aver_waitingTime=-1;//平均每位客户等待时间=sumWaitingTime/sumCusServed
    double per_second_servedCus=-1;//单位时间服务客户数=总服务顾客数/workTime
    // double queSizeMax=-1;//今日银行排队的最长是多少。
    // double queSizeMin=-1;//今日银行排队的最短是多少
    // 等候队列
    queue<Customer> waitingQueue;
    // 当日完成服务的历史客户列表
    vector<Customer> servedQueue;
public:
    Bank():workTime(24*60*60),windowNums(1),currTime(0){};
    Bank(int workTime,int windowNums,int currTime):workTime(workTime),windowNums(windowNums),currTime(currTime){};
    ~Bank(){};
    bool ifCustomerArrive()const;
    bool ifWindowsIdly()const;
    void simulation(int rounds=1);
    friend ostream & operator<<(ostream &out,Bank & bank)
    {
        out<<"bank Attribute:"<<endl;
        out<<"workTime:"<<bank.workTime<<endl;
        out<<"windowsNums:"<<bank.windowNums<<endl;
        if(bank.currTime<(bank.workTime-1))
        {
            out<<"please simulation!"<<endl;
            return out;
        }
        bank.sumCusServed=bank.servedQueue.size();
        bank.lastCus=bank.waitingQueue.size();
        bank.sumCusArrive=bank.sumCusServed+bank.lastCus;
        for(const auto &x:bank.servedQueue)
        {
            bank.sumWaitingTime+=x.get_WaitingTime();
        }
        bank.aver_waitingTime=bank.sumWaitingTime/bank.sumCusServed;
        bank.per_second_servedCus=bank.sumCusServed/bank.workTime;
        out<<"今日总服务客户数:"<<bank.sumCusServed<<endl;
        out<<"未服务客户数:"<<bank.waitingQueue.size()<<endl;
        out<<"总到达:"<<bank.sumCusArrive<<endl;
        out<<"总等候时间:"<<bank.sumWaitingTime<<endl;
        out<<"平均每位被服务客户等候时间:"<<bank.aver_waitingTime<<endl;
        out<<"单位时间内服务客户数:"<<bank.per_second_servedCus<<endl;     
        return out;
        
    };
};



#endif/* BANK_H_ */



// 结构能简单就简单，不要太多层次结构，除非真的必须。
// 不要为了代码阅读而刻意增加太多层次，尽量用注释搞定。
// 直接直接再直接，需求要核心简单，再不断完善，不要一次考虑太多维度，先实现，再有优化


